import base64
import datetime
import json
import math
import os
import random
import time
import traceback
from collections import defaultdict
from itertools import groupby

from PyQt6.QtCore import QRunnable, QProcess, QMutex, QThread

import Global
from HTTP.HttpUtil import HttpUtil
from NetManager.GameTx import GameTx
from Script.ErolabUtil import ErolabUtil
from Script.GameFun import GameFun
from Comm.ProxyUtil import ProxyUtil
from Comm.UploadData import UploadData
from Script.protobuf import protocol_pb2
from UserManager import UserManager
import re

from 加密.AESHelper import AESHelper


class ProcessPoolTask(QRunnable):
    _captcha_mutex = QMutex()
    file_mutex = QMutex()
    account_mutex = QMutex()
    def __init__(self, game_index,mode):
        super().__init__()
        self.game_index = game_index
        self.mode =mode
        #self.mutex = QMutex()
        self._is_running=True

    def run(self):
        try:
            Global.G_Game[self.game_index].data["status"]="联机"
            #Global.G_Game[self.game_index].data["notes"]="[启动]->启动中..."

            log_file = f"Log/窗口{self.game_index + 1}.log"
            Global.G_Game[self.game_index].Log = Global.create_file_logger(f"窗口{self.game_index + 1}", log_file, 10 * 1024 * 1024, 2)

            Global.LOGD(self.game_index, "[启动]->启动中...")
            Global.G_Game[self.game_index].data["status"] = "运行"


            Global.G_Game[self.game_index].isScriptRun=True
            country_code = Global.read_ini(Global.ConfigFileName, 'System', '国家', 'global')
            self.game = Global.G_Game[self.game_index]
            self.country_code =country_code
            # start = time.time()
            # r = random.Random()
            # wait_value = r.randint(1, 30)
            while self.game.isScriptRun:
                try:
                    # end= time.time()
                    # Global.LOGD(self.game_index,f"[等待]->随机等待:{wait_value}秒,剩余:{wait_value-int(end-start)}")
                    # if (end-start) <wait_value:
                    #     time.sleep(1)
                    #     continue

                    show_netip = Global.G_GlobalConfig.get("show_netip", '')
                    enable_proxy = Global.G_GlobalConfig.get('enable_proxy', False)
                    if self.game.proxy==None:
                        try:
                            Global.G_Game[self.game_index].proxy= ProxyUtil.get_ip()
                        except Exception as e:
                            Global.LOGE(self.game_index, f"[异常]->获取代理异常:{e}")
                            continue
                    if enable_proxy and self.game.proxy==None:
                        Global.LOGD(self.game_index, f"[代理]->等待切换IP")
                        continue
                    if show_netip and self.game.proxy==None:
                        公网IP = ProxyUtil.GetInternetIP(Global.G_Game[self.game_index].proxy)
                        self.game.data["proxyIP"] =公网IP
                        Global.LOGD(self.game_index, f"[IP]->公网IP:{公网IP}")
                    if self.game.proxy:
                        self.game.data["proxyIP"] = self.game.proxy.get("ip","") + ":" + str(self.game.proxy.get("port",0))

                    with GameFun(player_id=self.game.data["user"],device_id=self.game.data["pass"],android_id=self.game.data["user_id"], index=self.game_index,proxy_info=self.game.proxy,country_code=country_code,gamedata=self.game) as gameFun:
                        self.game_fun = gameFun
                        self.game.GameFun = gameFun
                        if self.mode in(1,2) and not self.game.data["user"]:
                            Global.LOGD(self.game_index, f"[注册]->开始注册")
                            isSuccess,status_code,resp =gameFun.sign_up()
                            if not isSuccess:
                                Global.LOGE(self.game_index, f"[注册]->注册失败")
                                ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                self.game.proxy = None
                                continue
                            self.game.data['user'] =gameFun.player_id
                            self.game.data['pass'] =gameFun.device_id.upper()
                            self.game.data['user_id'] = gameFun.android_id.upper()
                            user_data={"user":self.game.data['user'],"pass":self.game.data['pass'],"user_id":self.game.data['user_id'],"country":country_code}
                            UserManager.insert_user(user_data)
                            Global.LOGD(self.game_index, "[注册]->成功")
                            if self.mode == 1:
                                self.InitData()
                                ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                self.game.proxy = None
                                continue
                            else:
                                UserManager.update_user_status(self.game.data['user'], UserManager.STATUS_RUNNING)
                            continue  #自动模式重新开始,但是不清楚数据

                        Global.LOGD(self.game_index, "[登陆]->开始登陆")
                        isSuccess,status_code,resp =gameFun.sign_in()
                        if not isSuccess:
                            Global.LOGE(self.game_index, f"[登陆]->登陆失败:{status_code}")
                            ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                            self.game.proxy = None
                            continue
                        if len(resp['resultData']['playerInfo']['idpInfo']) >0:
                            if resp['resultData']['playerInfo']['idpInfo'][0]['key']:
                                user_data = {
                                    "notes": "已绑定邮箱",
                                    "flag": UserManager.STATUS_FAILED,
                                }
                                UserManager.update_user_by_name(self.game.data['user'], user_data)
                                self.账号_切换()
                                continue
                        self.game.isInit = False
                        self.game.isRepetition_Battle = False
                        self.game.isInBattle = False
                        self.game.Result=None
                        if not self.game.game_ip and not self.game.game_port:
                            with GameTx(game_index=self.game_index,chacha_key=gameFun.GateWay_Key,chacha_nonce=gameFun.Nonce) as gateway:
                                self.game.GateWay = gateway
                                #全球服
                                if country_code=="KR":
                                    ip ="gs-tskgb-gateway.netmarble.com"
                                elif country_code=="JP":
                                    ip = "gs-tskgb-t2-gateway.netmarble.com"
                                elif country_code == "TW":
                                    ip = "gs-tskgb-t3-gateway.netmarble.com"#IOS服务器
                                elif country_code == "SG":#新加坡
                                    ip = "gs-tskgb-t4-gateway.netmarble.com"
                                elif country_code == "US":#新加坡
                                    ip = "gs-tskgb-t5-gateway.netmarble.com"
                                if not gateway.Connect(ip=ip,port=30101,proxy=self.game.proxy):
                                    Global.LOGE(self.game_index,f"[通讯]->网关连接失败")
                                    continue
                                Global.LOGD(self.game_index, f"[通讯]->网关连接成功")
                                time.sleep(1)
                                #1、CGGetNMSSTokenReq
                                CGGetNMSSTokenReq = protocol_pb2.CGGetNMSSTokenReq()
                                CGGetNMSSTokenReq.PlatformType = protocol_pb2.EPlatformType.AOS
                                CGGetNMSSTokenReq.PID =self.game.data['user']
                                gateway.SendPacket(CGGetNMSSTokenReq)
                                self.game_fun.WaitResult()
                                #Error = self.game.Result.get("Error", None)
                                #2、CGAppCertificationReq
                                # CGAppCertificationReq = protocol_pb2.CGAppCertificationReq()
                                #3、CGAuthLoginReq
                                CGAuthLoginReq = protocol_pb2.CGAuthLoginReq()
                                CGAuthLoginReq.AuthToken=gameFun.authToken
                                CGAuthLoginReq.Pid = self.game.data['user']
                                CGAuthLoginReq.NetmarbleSDKAuth =True
                                CGAuthLoginReq.PlatformType = protocol_pb2.EPlatformType.AOS
                                CGAuthLoginReq.NaverWorksCertCode = 0
                                CGAuthLoginReq.Version = gameFun.appVersion
                                CGAuthLoginReq.JoinedCountry = country_code
                                CGAuthLoginReq.DLCVersion = gameFun.DLCVersion
                                CGAuthLoginReq.GameDataVersion = '0'
                                gateway.SendPacket(CGAuthLoginReq)
                                self.game_fun.WaitResult()
                                Error = self.game.Result.get("Error",None)
                                WaitingOrder = self.game.Result.get("WaitingOrder", 0)
                                IsDBWaiting = self.game.Result.get("IsDBWaiting", False)
                                if Error:
                                    if Error=="E_MAINTENANCE_SERVER":
                                        Global.LOGE(self.game_index, f"[网关]->服务器维护中...")
                                        break
                                    elif Error=="E_PLAYER_BANNED":
                                        Global.LOGE(self.game_index, f"[账号]->已封号")
                                        user_data = {
                                            "notes": "已封号",
                                            "flag": UserManager.STATUS_FAILED,
                                        }
                                        UserManager.update_user_by_name(self.game.data['user'], user_data)
                                        self.账号_切换()
                                        continue
                                    Global.LOGE(self.game_index,f"[网关]->错误：{Error}")
                                elif WaitingOrder>0 or IsDBWaiting:
                                    Global.LOGD(self.game_index, f"[通讯]->排队等待:{WaitingOrder},服务器响应:{IsDBWaiting}")
                                    while self.game.GateWay.connected:
                                        time.sleep(3)
                                        if self.game.game_ip and self.game.game_port:
                                            break
                                        if not IsDBWaiting:
                                            CGGetWaitingQueueOrderReq = protocol_pb2.CGGetWaitingQueueOrderReq()
                                            CGGetWaitingQueueOrderReq.JoinedCountry = country_code
                                            gateway.SendPacket(CGGetWaitingQueueOrderReq)
                                            self.game_fun.WaitResult()
                                            WaitingOrder = self.game.Result.get("WaitingOrder", 0)#IsDBWaiting
                                            if WaitingOrder>0:
                                                Global.LOGD(self.game_index, f"[通讯]->排队等待:{WaitingOrder},服务器响应:{IsDBWaiting}")
                                        time.sleep(1)
                                        self.game.game_ip = self.game.Result.get("ConnectedIP", "")
                                        self.game.game_port = self.game.Result.get("ConnectedPort", 0)
                                        if self.game.game_ip and self.game.game_port:
                                            break

                                else:
                                    self.game.game_ip = self.game.Result.get("ConnectedIP", "")
                                    self.game.game_port = self.game.Result.get("ConnectedPort", 0)



                        self.game.GateWay =None
                        if not self.game.game_ip and not self.game.game_port:
                            continue

                        with GameTx(game_index=self.game_index,chacha_key=gameFun.Game_Key,chacha_nonce=gameFun.Nonce) as gameTx:
                            self.game.Game = gameTx
                            if not self.game.Game.Connect(ip=self.game.game_ip,port=self.game.game_port,proxy=self.game.proxy):
                                Global.LOGE(self.game_index,f"[通讯]->连接游戏服务器失败")
                                self.game.game_ip = ''
                                self.game.game_port = 0
                                continue
                            Global.LOGD(self.game_index, f"[通讯]->连接游戏服务器成功")
                            self.game_fun.Req_CALoginReq()
                            Error = self.game.Result.get("Error", None)
                            if Error:
                                Global.LOGE(self.game_index, f"[登陆]->错误：{Error}")
                                ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                self.game.proxy = None
                                self.game.game_ip = ""
                                self.game.game_port = 0
                                continue
                            Global.LOGD(self.game_index,f"[提示]->等待数据加载")
                            self.game_fun.Req_CAGetPlayerReq()
                            self.game_fun.WaitResult()
                            Error = self.game.Result.get("Error", None)
                            if Error:
                                Global.LOGE(self.game_index, f"[登陆]->错误：{Error}")
                                ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                self.game.proxy = None
                                continue
                            if not self.Handle_Script():
                                if not self.game.isScriptRun:
                                    Global.LOGE(self.game_index, f"[提示]->手动停止")
                                    break
                                if not self.game.Game.connected:
                                    Global.LOGE(self.game_index, f"[通讯]->通讯异常断开,正在重连...")
                                    time.sleep(3)
                                    ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                    self.game.proxy = None
                                    continue
                                Global.LOGE(self.game_index, f"[脚本]->脚本运行异常,正在重连...")
                                time.sleep(3)
                                ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                self.game.proxy = None
                                continue

                            if not self.game.Game.connected:
                                Global.LOGE(self.game_index, f"[通讯]->通讯异常断开,正在重连...")
                                time.sleep(3)
                                ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                                self.game.proxy = None
                                continue
                            Global.LOGD(self.game_index, f"[卡片]->开始统计卡片信息")
                            上传数据 = []
                            上传数据名称 =[]
                            卡片名 = []
                            宠物名 = []
                            hero_list = self.game.Info['player_hero']
                            # support_card_list = self.game.Info['Player'].get('support_card_list', [])
                            for hero_info in hero_list:
                                HeroTid = hero_info['HeroTid']
                                card_cfg = self.取卡片配置信息("pctable", HeroTid)
                                if card_cfg and card_cfg['Rarity'] == 4:
                                    name = card_cfg['name']
                                    code = UploadData.GetRoleCode(name)
                                    卡片名.append(name)
                                    if code:
                                        上传数据.append(code)
                                        上传数据名称.append(name)

                            卡片数据 = ""
                            if len(卡片名) > 0:
                                卡片数据 = f"角色:[{','.join(卡片名)}]"
                            # if len(支援卡片名) > 0:
                            #     if 卡片数据:
                            #         卡片数据 += " "
                            #     卡片数据 += f"支援:[{','.join(支援卡片名)}]"

                            资源信息 = f"英雄:{len(卡片名)},英雄召唤使用券:{self.取_货币数量(506)},甄选英雄召唤使用券:{self.取_货币数量(508)},红宝石:{self.game.data['diamond']}"
                            if len(卡片名) > 0:
                                user_data = {
                                    "name": self.game.data['roleName'],
                                    "flag": UserManager.STATUS_SUCCESS,
                                    "level": self.game.data['level'],
                                    'card_name': 卡片数据,
                                    "source_info": 资源信息,
                                }
                                UserManager.update_user_by_name(self.game.data['user'], user_data)
                            else:
                                user_data = {
                                    "name": self.game.data['roleName'],
                                    "level": self.game.data['level'],
                                    "flag": UserManager.STATUS_FAILED,
                                    'card_name': 卡片数据,
                                    "source_info": 资源信息
                                }
                                UserManager.update_user_by_name(self.game.data['user'], user_data)
                            if len(卡片名) > 0:
                                # 上传自选代码,绑定邮箱失败的不上传
                                isSuccess, result = UploadData.upload_data(username=self.game.data["user"],
                                                                           userpass=self.game.data['pass'],
                                                                           rolename=",".join(上传数据),
                                                                           rolenum=len(上传数据), text=资源信息,
                                                                           email=self.game.data['email'],
                                                                           emailpass=self.game.data['email_pass'],
                                                                           上传数据名称 = 上传数据名称)
                                if isSuccess:
                                    Global.LOGD(self.game_index, f"[上传]->上传数据成功:{result}")
                                    Global.G_Game[self.game_index].data['produceUploadCount'] += 1
                                    user_data = {"flag": UserManager.STATUS_UPLOAD, "upload_id": result}
                                    UserManager.update_user_by_name(self.game.data['user'], user_data)
                                else:
                                    Global.LOGE(self.game_index,
                                                f"[上传]->账号:{self.game.data['user']},上传失败:{result}")
                                    user_data = {"notes": result}
                                    UserManager.update_user_by_name(self.game.data['user'], user_data)
                                Global.G_Game[self.game_index].data['produceAccount'] += 1
                        self.game.Game = None
                        self.game.GameFun = None
                        Global.LOGD(self.game_index, f"[提示]->执行完毕")
                        time.sleep(2)
                        if self.账号_切换():
                            continue
                        break


                except Exception as e:
                    traceback.print_exc()
                    Global.LOGE(self.game_index,f"脚本异常:{e}")
                    if self.mode ==2:
                        ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
                        self.game.proxy = None
                        self.InitData()
        except Exception as e:
            error_msg = f"线程：{str(e)}"
            self.LOGE(error_msg)  # 记录详细错误信息
            if self.game_index<len(Global.G_Game):
                Global.G_Game[self.game_index].isScriptRun = False
                Global.G_Game[self.game_index].data["status"] = "脱机"
        finally:
            ProxyUtil.remove_ip_from_blacklist(self.game.proxy)
            if self.game_index<len(Global.G_Game):
                Global.G_Game[self.game_index].isScriptRun = False
                Global.G_Game[self.game_index].data["status"] = "脱机"
            
                Global.G_Game[self.game_index].Log.remove()
                Global.G_Game[self.game_index].Log = None
    def 账号_切换(self):
        if self.mode == 2:
            Global.LOGD(self.game_index, f"[提示]->初始化数据")
            self.InitData()
            return True
        elif self.mode == 4:  # 账号模式
            run_account_data = UserManager.get_user_info(1)
            if len(run_account_data) > 0:
                Global.LOGD(self.game_index, f"[提示]->更换账号")
                self.InitData()
                Global.G_Game[self.game_index].data['user'] = run_account_data[0].get('user', '')
                Global.G_Game[self.game_index].data['pass'] = run_account_data[0].get('pass', '')
                Global.G_Game[self.game_index].data['user_id'] = run_account_data[0].get('user_id', '')
                Global.G_Game[self.game_index].data['token'] = run_account_data[0].get('token', '')
                Global.G_Game[self.game_index].data['account_info'] = run_account_data[0].get('account_info', '')
                Global.G_Game[self.game_index].data['upload_id'] = run_account_data[0].get('upload_id', '')
                if run_account_data[0].get('mail') and '@' in run_account_data[0].get('mail', ''):
                    Global.G_Game[self.game_index].data['email'] = run_account_data[0].get('mail', '')
                    Global.G_Game[self.game_index].data['email_pass'] = run_account_data[0].get('mail_pass', '')
                return True
        return False
    def InitData(self):
        Global.G_Game[self.game_index].data["token"] = ""
        Global.G_Game[self.game_index].data["level"] = 0
        Global.G_Game[self.game_index].data["power"] = 0
        Global.G_Game[self.game_index].data["diamond"] = 0
        Global.G_Game[self.game_index].data["roleName"]=''
        Global.G_Game[self.game_index].data['glod']=0
        Global.G_Game[self.game_index].data['money'] = 0
        Global.G_Game[self.game_index].data['bindYB'] = 0
        Global.G_Game[self.game_index].data['user'] = ""
        Global.G_Game[self.game_index].data['pass'] = ""
        Global.G_Game[self.game_index].data['user_id'] = ""
        Global.G_Game[self.game_index].data['email'] = ""
        Global.G_Game[self.game_index].data['email_pass'] = ""
        Global.G_Game[self.game_index].data['account_info'] = ""
        Global.G_Game[self.game_index].data['upload_id'] =""
        #Global.G_Game[self.game_index].proxy=None
        Global.G_Game[self.game_index].Info = {}
        Global.G_Game[self.game_index].Result = {}
        Global.G_Game[self.game_index].isInit = False
        Global.G_Game[self.game_index].isInBattle = False
        Global.G_Game[self.game_index].isRepetition_Battle = False
        Global.G_Game[self.game_index].isTrain = False
    def LOGD(self,data):
        Global.LOGD(self.game_index,data)
        self._safe_update_game_data("notes", data)
    def LOGE(self,data):
        Global.LOGE(self.game_index,data)
    def 跳过剧情(self,id,status =0):
        if status == 0:
            self.game_fun.Req_CATutorialStartReq(id)
            Error = self.game.Result.get('Error',None)
            if Error:
                Global.LOGE(self.game_index,f"[引导]-开始引导失败:{Error}")
                return False
        self.game_fun.Req_CATutorialEndReq(id)
        Error = self.game.Result.get('Error', None)
        if Error:
            Global.LOGE(self.game_index, f"[引导]-结束引导失败:{Error}")
            return False
        Status =self.game.Result['Tutorials'][0]['Status']
        return Status == 3

    def 自动_邮件(self):
        while self.game.Game.connected:
            Global.LOGD(self.game_index,f"[邮件]->查询邮件")
            self.game_fun.Req_CAGetMailListReq()
            Mails = self.game.Info.get("mail",None)
            if not Mails:
                time.sleep(2)
                continue
            TotalMailCount =Mails['TotalMailCount']
            if TotalMailCount == 0:
                return True
            else:
                Mails = self.game.Info["mail"].get("Mails", None)
                if Mails:
                    可读邮件列表 = [mail for mail in Mails if mail["Status"] == 1]
                    if len(可读邮件列表)>0:
                        Global.LOGD(self.game_index, f"[邮件]->收取所有邮件,数量:{TotalMailCount}")
                        self.game_fun.Req_CAMailReadAllReq()
                Global.LOGD(self.game_index, f"[邮件]->删除已读邮件")
                self.game_fun.Req_CAMailDeleteAllReq()
                time.sleep(2)
        return False

    def 自动_关卡(self):
        stage_list = [100002,100003,100004,100005,100006,100007,100008,100009,100010,100011,100012,100013,100014,100015,100016,100017,100018,100019,100020,200001,200002,200003,200004,200005,200006,200007,200008,200009,200010,200011,200012,200013,200014,200015]
        for stage_id in stage_list:
            battle_215 = Global.G_GlobalConfig.get('battle_215',False)
            if not battle_215:
                if stage_id >200001:
                    return True
            stage_info =self.关卡_完成信息(stage_id)
            if not stage_info:#这里校验体力
                if self.game.data['power']< 6:
                    Global.LOGD(self.game_index,f"[体力]->体力不足,当前值:{self.game.data['power']}")
                    cur_item = next((item for item in self.game.Info['inventory_consumable'] if item['ItemTemplateID']==204000001),None)
                    if cur_item:
                        Global.LOGD(self.game_index,f"[背包]->使用消耗品,ID:{204000001},数量:{cur_item['Count']}")
                        self.game_fun.Req_CAOpenItemBoxReq(int(cur_item['ItemUniqueID']))
                    else:
                        Global.LOGD(self.game_index, f"[体力]->体力箱数量不足")
                        return True
                if not self.关卡_战斗(stage_id):
                    return False
                if stage_id == 100002:
                    self.打开_功能([200, 3300, 3400, 3700, 3800, 5600, 6000, 6100])
                if stage_id == 100006:
                    self.自动_跳过剧情([901])
                    self.打开_功能([400])#开启强化功能
                if stage_id == 100020:
                    self.自动_跳过剧情([1101])
                    self.打开_功能([600, 700, 4100, 4200, 4300, 4400])
                if stage_id == 200001:
                    self.自动_跳过剧情([2001])
                    self.打开_功能([1900])
        return True

    def 关卡_完成信息(self,stage_id):
        StageResults = self.game.Info['player_stage'].get('StageResults', None)
        if StageResults:
            stage_info = next((stage for stage in StageResults if stage['StageId'] == stage_id and stage['CompleteStar']>0), None)
            return stage_info
        return None
    def 关卡_战斗(self,stage_id):
        try:
            self.编组_设置编组()
            Global.LOGD(self.game_index, f"[关卡]->开始战斗,ID:{stage_id}")
            self.game_fun.Req_CAEnterStageReq(stage_id,2)
            Error = self.game.Result.get("Error",None)
            if Error:
                Global.LOGD(self.game_index, f"[关卡]->开始战斗失败,ID:{stage_id},错误:{Error}")
                return False
            while self.game.Game.connected :
                time.sleep(2)
                if not self.game.isInBattle:
                    break
            else:
                Global.LOGE(self.game_index,f"[关卡]->通讯异常断开")
                return False
            Error = self.game.Result.get("Error", None)
            if Error:
                Global.LOGD(self.game_index, f"[关卡]->开始战斗失败,ID:{stage_id},错误:{Error}")
                return False
            WinTeam =self.game.Result.get('WinTeam',0)
            if WinTeam == 1:
                StageId =self.game.Result['StageResult']['StageId']
                CompleteStar = self.game.Result['StageResult']['CompleteStar']
                PlayTimeSec = self.game.Result['PlayTimeSec']
                TotalTurn = self.game.Result['TotalTurn']
                Global.LOGD(self.game_index,f"[关卡]->完成战斗,ID:{StageId},星级:{CompleteStar},耗时:{PlayTimeSec}")
                #self.game_fun.Req_CALeaveStageReq(stage_id)
                return True
            else:
                Global.LOGD(self.game_index, f"[关卡]->完成战斗失败,ID:{stage_id}")
                #self.game_fun.Req_CALeaveStageReq(stage_id)
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->关卡_战斗:{e},ID:{stage_id}")
        return False
    def 取_英雄列表(self,count=5,Repetition=False):
        hero_list = self.game.Info['player_hero']
        for hero in hero_list:
            config = self.取卡片配置信息('pctable',hero['HeroTid'])
            if config :
                hero['Rarity'] =config['Rarity']
                hero['Star'] = config['Star']
        hero_sort = [hero for hero in sorted(hero_list,key=lambda x: (-x['Lv'], -x.get('Rarity', 0), -x.get('Star', 0),-x['ReinforceLevel']))]
        if Repetition:
            ret_hero_list=[]
            main_hero = hero_sort[:1][0]['HeroUid']
            newhero_sort = list(filter(lambda hero: hero["Lv"] <30, hero_sort))
            for hero_id in  newhero_sort[:4]:
                ret_hero_list.append(hero_id['HeroUid'])
            ret_hero_list.append(main_hero)
            return ret_hero_list
        hero_uids = [hero['HeroUid'] for hero in hero_sort]
        return hero_uids[:count]
    def 编组_设置编组(self,deck_type=1,repetition=False):
        Decks =self.game.Info['player_deck'].get("Decks",None)
        是否编组 = False
        FormationGroup = 0
        if repetition:
            FormationGroup = 14100
        if Decks:
            cur_deck = next((deck for deck in Decks if deck['DeckType'] == deck_type),None)  #只获取type为1的编组数据
            if cur_deck:
                DeckPositionUID1 = cur_deck['DeckPositionUID1']
                DeckPositionUID2 = cur_deck['DeckPositionUID2']
                DeckPositionUID3 = cur_deck['DeckPositionUID3']
                DeckPositionUID4 = cur_deck['DeckPositionUID4']
                DeckPositionUID5 = cur_deck['DeckPositionUID5']
                FormationGroup = cur_deck['Formation']['FormationGroup']
                if DeckPositionUID1=="0" or DeckPositionUID2=="0" or DeckPositionUID2=="0" or DeckPositionUID3=="0" or DeckPositionUID4=="0" or DeckPositionUID5=="0":
                    是否编组 = True
            else:
                是否编组 =True
        if 是否编组:
            deck_list = self.取_英雄列表(5,repetition)
            self.game_fun.Req_CASavePlayerDeckReq(deck_list, FormationGroup,deck_type)
            self.game_fun.Req_CASetPreOrderSkillReq(deck_type, deck_list)  # 设置技能释放,取前3个英雄 随机设置第一个或者第二个技能
        self.打开_功能()
    def 打开_功能(self,content_list=None):
        if not content_list:
            content_list = []
        if self.关卡_完成信息(100004):
            content_list.append(3900)
            content_list.append(4000)
        要打开的功能=[]
        for content_id in content_list:
            cur_content = next((con for con in self.game.Info['player_contents'] if con['ContentsID'] ==content_id ),None)
            if not cur_content:
                要打开的功能.append(content_id)
        if len(要打开的功能) > 0:
            self.game_fun.Req_CAContentsUnlockReq(要打开的功能)
    def 是否_持有英雄卡片(self,hero_id):
        hero_list = self.game.Info['player_hero']
        hero_info = next((hero for hero in hero_list if hero['HeroTid'] == hero_id),None)
        return hero_info
    def 抽卡_默认抽卡(self,gacha_id):
        if not self.是否_持有英雄卡片(100654) and gacha_id == 19:
            self.game_fun.Req_CAGetGachaReq()
            gacha_list = self.game.Info['player_gacha']
            cur_gacha = next((gacha_info for gacha_info in gacha_list if gacha_info['GachaTID'] == gacha_id),None)
            if cur_gacha:
                self.game_fun.Req_CADrawGachaReq(gacha_id)
                time.sleep(1)
        elif gacha_id == 15:
            gacha_list = self.game.Info['player_gacha']
            gacha_info= next((gacha for gacha in gacha_list if gacha['GachaTID'] == gacha_id),None)
            if gacha_info and gacha_info['DrawCount'] <gacha_info['DrawLimit']:
                self.game_fun.Req_CADrawGachaReq(gacha_id,True)
                time.sleep(1)
    def 普通_抽卡(self):
        try:
            roll_506 = Global.G_GlobalConfig.get("roll_506", False)
            if not roll_506:
                return True
            self.game_fun.Req_CAGetGachaReq()
            gacha_list = self.game.Info['player_gacha']
            抽卡ID列表_506 = [dbcgacha['TID'] for dbcgacha in Global.G_Dbc['gacha'] if dbcgacha['CurrencyID'] == 506]
            cur_gacha = next((gacha_info for gacha_info in gacha_list if gacha_info['GachaTID'] in 抽卡ID列表_506))
            if cur_gacha:
                GachaTID = cur_gacha['GachaTID']
                if int(time.time()) * 1000 <= int(cur_gacha['ExpirationTimeMs']) and cur_gacha['DrawCount'] <cur_gacha['DrawLimit']:
                    gacha_cf = next((dbcgacha for dbcgacha in Global.G_Dbc['gacha'] if dbcgacha['TID'] == int(GachaTID)), None)
                    if not gacha_cf:
                        return True
                    CurrencyID = gacha_cf['CurrencyID']
                    Currency_Name = next((currency['name'] for currency in Global.G_Dbc['currency_etc'] if currency['CurrencyID'] == CurrencyID), '')
                    Ruby = gacha_cf['Ruby']
                    抽卡次数 = 0
                    use_diamond = False
                    while self.game.Game.connected:
                        是否连抽 = False
                        UseTicket = True
                        召唤卡数量 = self.取_货币数量(CurrencyID)
                        红宝石数量 = self.取_货币数量(501)
                        if 召唤卡数量 == 0 and not use_diamond:
                            break
                        elif 召唤卡数量 == 0 and 红宝石数量 < Ruby:
                            break
                        elif 召唤卡数量 == 0 and use_diamond:
                            UseTicket = False
                        if 召唤卡数量 >= 10 or (use_diamond and 红宝石数量 >= Ruby * 10):
                            是否连抽 = True
                        Global.LOGD(self.game_index,f"[普通抽卡]->ID:{GachaTID},消耗：{Currency_Name},连抽:{是否连抽},红宝石:{not UseTicket},抽卡次数：{抽卡次数 + 1}")
                        self.game_fun.Req_CADrawGachaReq(int(GachaTID), 是否连抽, UseTicket)
                        time.sleep(1)
                        抽卡次数 += 1
                        Error = self.game.Result.get("Error", None)
                        if Error:
                            Global.LOGE(self.game_index, f"[普通抽卡]->ID:{GachaTID},失败")
                            break
            return True
        except Exception as e:
            Global.LOGE(self.game_index,f"[异常]->普通_抽卡:{e}")
        return False
    def 自动_抽卡(self):
        try:
            is_roll = Global.G_GlobalConfig.get("is_roll",False)
            if not is_roll:
                return True
            roll_id = Global.G_GlobalConfig.get("roll_id", '')
            if not is_roll:
                return True
            roll_id = int(roll_id)
            use_diamond = Global.G_GlobalConfig.get("use_diamond", False)
            self.game_fun.Req_CAGetGachaReq()
            gacha_list =self.game.Info['player_gacha']
            cur_gacha = next((gacha_info for gacha_info in gacha_list if gacha_info['GachaTID'] == roll_id),None)
            if cur_gacha:
                GachaTID = cur_gacha['GachaTID']
                if int(GachaTID) == roll_id and int(time.time()) * 1000 <= int(cur_gacha['ExpirationTimeMs']) and cur_gacha['DrawLimit']==0:
                    gacha_cf = next((dbcgacha for dbcgacha in Global.G_Dbc['gacha'] if dbcgacha['TID'] == int(GachaTID)), None)
                    if not gacha_cf:
                        return True
                    CurrencyID = gacha_cf['CurrencyID']
                    Currency_Name = next((currency['name'] for currency in Global.G_Dbc['currency_etc'] if currency['CurrencyID'] == CurrencyID),'')
                    Ruby = gacha_cf['Ruby']
                    抽卡次数 = 0
                    while self.game.Game.connected:
                        是否连抽 = False
                        UseTicket = True
                        召唤卡数量 = self.取_货币数量(CurrencyID)
                        红宝石数量 = self.取_货币数量(501)
                        if 召唤卡数量 == 0 and not use_diamond:
                            break
                        elif 召唤卡数量 == 0 and 红宝石数量<Ruby:
                            break
                        elif 召唤卡数量==0 and use_diamond:
                            UseTicket = False
                        if 召唤卡数量 >= 10 or (use_diamond and 红宝石数量 >= Ruby*10):
                            是否连抽 = True
                        Global.LOGD(self.game_index, f"[抽卡]->ID:{GachaTID},消耗：{Currency_Name},连抽:{是否连抽},红宝石:{not UseTicket},抽卡次数：{抽卡次数+1}")
                        self.game_fun.Req_CADrawGachaReq(int(GachaTID), 是否连抽, UseTicket)
                        time.sleep(1)
                        抽卡次数 += 1
                        Error = self.game.Result.get("Error", None)
                        if Error:
                            Global.LOGE(self.game_index, f"[抽卡]->ID:{GachaTID},失败")
                            break
            return True
        except Exception as e:
            Global.LOGE(self.game_index,f"[异常]->自动_抽卡:{e}")
        return False

    def 取_货币数量(self,id):
        player_etc =self.game.Info['player_etc']
        return next((currency['Value'] for currency in player_etc if currency['ID']==id),0)
    def 取卡片配置信息(self,dbc_name,id):
        try:
             dbc_list = Global.G_Dbc.get(dbc_name,None)
             if not dbc_list:
                 return None
             return next((dbc for dbc in dbc_list if dbc['TID']==id),None)
        except Exception as e:
            Global.LOGD(self.game_index, f"[异常]->取卡片配置信息:{e},DBC:{dbc_name},ID:{id}")
        return None

    def 引导_穿戴装备(self):
        引导装备是否穿戴 = False
        穿戴装备 = None
        for equip in self.game.Info['inventory_weapon']:
            if equip['ItemTemplateID'] == 10121001:
                if int(equip['EquipHeroUID']) > 0:
                    引导装备是否穿戴 = True
                穿戴装备 = equip
                break

        if not 引导装备是否穿戴 and 穿戴装备:
            HeroUid = next((int(hero['HeroUid']) for hero in self.game.Info['player_hero'] if hero['HeroTid'] == 100514), 0)
            if HeroUid > 0:
                self.game_fun.Req_CAHeroEquipItemReq(HeroUid, 2, int(穿戴装备['ItemUniqueID']))
        if 穿戴装备 and 穿戴装备['ReinforceLevel']<1:
            目标等级 = 穿戴装备['ReinforceLevel'] + 1
            #Global.LOGD(self.game_index, f"[装备强化]->ID:{穿戴装备['ItemUniqueID']},目标等级:{目标等级}")
            self.game_fun.Req_CAItemReinforceReq(int(穿戴装备['ItemUniqueID']), 目标等级)

    def 自动_重复关卡战斗(self):
        try:
            is_repetition_battle=Global.G_GlobalConfig.get('repetition_battle',False)
            if not is_repetition_battle:
                return True
            stagge_id = 200001
            count = 30
            if not self.关卡_完成信息(stagge_id):
                Global.LOGE(self.game_index, f"[重复关卡]->未完成关卡2-1")
                return True
            repetition_battle = self.game.Info.get('repetition_battle', None)
            if repetition_battle:
                if repetition_battle.get('BattleInfo',None):
                    ProcessState = repetition_battle['BattleInfo']['ProcessState']
                    if ProcessState == 2:
                        self.game_fun.Req_CARepetitionBattleResultReq()
                        time.sleep(2)
                    elif ProcessState == 1:
                        return True
            self.game.Info['repetition_battle'] = None
            self.编组_设置编组(6,True)
            Global.LOGD(self.game_index, f"[重复关卡]->开始战斗,关卡:{stagge_id},次数:{count}")
            self.game_fun.Req_CARepetitionBattleEnterStageReq(stagge_id, count)
            Error = self.game.Result.get("Error",None)
            if Error:
                Global.LOGE(self.game_index,f"[重复关卡]->开始战斗失败:{Error}")
                return True
            self.game_fun.Req_CAChangeRepetitionBackgroundModeReq()  # 把重复战斗处理为后台
            # time.sleep(1)
            # while self.game.isRepetition_Battle:
            #     repetition_battle = self.game.Info.get('repetition_battle', None)
            #     if repetition_battle:
            #         ProcessState = repetition_battle['BattleInfo']['ProcessState']
            #         if ProcessState == 3:
            #             WinCount = repetition_battle['BattleInfo']['WinCount']
            #             LostCount = repetition_battle['BattleInfo']['LostCount']
            #             TotalUsedKey = repetition_battle['BattleInfo']['TotalUsedKey']
            #             Global.LOGD(self.game_index,
            #                         f"[重复关卡]->开始重复关卡战斗,关卡:{stagge_id},胜利/失败/总数:{WinCount}/{LostCount}/{count},消耗:{TotalUsedKey}")
            #             self.game.isRepetition_Battle = False
            #         elif ProcessState == 2:
            #             self.game_fun.Req_CARepetitionBattleResultReq()
            #     time.sleep(2)
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->自动_重复关卡战斗:{e}")
        return False
    def 自动_图鉴奖励(self):
        try:
            if not self.game.Info.get('player_book',None):
                return True
            HeroCollectionBook = self.game.Info['player_book'].get('HeroCollectionBook', [])
            PetCollectionBook = self.game.Info['player_book'].get('PetCollectionBook', [])
            ItemCollectionBook = self.game.Info['player_book'].get('ItemCollectionBook', [])

            group_ids = [
                config['GroupTID']
                for hero_info in self.game.Info['player_hero']
                if (config := self.取卡片配置信息('pctable', hero_info['HeroTid']))
            ]

            for book_info in HeroCollectionBook:
                GroupTID = book_info['GroupTID']
                if not book_info['Reward'] and GroupTID in group_ids:
                    config = next((collect_book for collect_book in Global.G_Dbc['collection_book'] if collect_book['GroupTID'] == GroupTID), None)
                    if config and config['Reward'] > 0:
                        BookType = config['BookType']
                        Global.LOGD(self.game_index,f"[图鉴]->领取英雄图鉴奖励,ID:{GroupTID},类型:{BookType}")
                        self.game.GameFun.Req_CACollectionBookRewardReq([GroupTID], BookType)
            # for book_info in PetCollectionBook:
            #     GroupTID = book_info['GroupTID']
            #     if not book_info['Reward'] and GroupTID in group_ids:
            #         config = next((collect_book for collect_book in Global.G_Dbc['collection_book'] if collect_book['GroupTID'] == GroupTID), None)
            #         if config and config['Reward'] > 0:
            #             BookType = config['BookType']
            #             Global.LOGD(self.game_index,f"[图鉴]->领取宠物图鉴奖励,ID:{GroupTID},类型:{BookType}")
            #             self.game.GameFun.Req_CACollectionBookRewardReq([GroupTID], BookType)
            # for book_info in ItemCollectionBook:
            #     GroupTID = book_info['GroupTID']
            #     if not book_info['Reward'] and GroupTID in group_ids:
            #         config = next((collect_book for collect_book in Global.G_Dbc['collection_book'] if
            #                        collect_book['GroupTID'] == GroupTID), None)
            #         if config and config['Reward'] > 0:
            #             BookType = config['BookType']
            #             Global.LOGD(self.game_index, f"[图鉴]->领取物品图鉴奖励,ID:{GroupTID},类型:{BookType}")
            #             self.game.GameFun.Req_CACollectionBookRewardReq([GroupTID], BookType)
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->自动_图鉴奖励:{e}")
        return False
    def 活动_远征队_前置任务(self):
        try:
            #装备强化6次,需要可升级6星的装备
            #检测任务是否完成
            Mission_list = self.game.Info['guide_mission'].get('Missions',None)
            if Mission_list:
                cur_mission = next((mission for mission in Mission_list if mission['MissionID']==9),None)
                if not cur_mission or cur_mission['IsComplete']==False:
                    inventory_weapon = self.game.Info.get('inventory_weapon', None)#10131001
                    if inventory_weapon:
                        cur_weapon =next((item for item in inventory_weapon if item['ItemTemplateID'] == 10131001 and item['ReinforceLevel']<6),None)
                        强化加6的武器 = next((item for item in inventory_weapon if item['ReinforceLevel'] == 6), None)
                        if cur_weapon and not 强化加6的武器:
                            目标等级 =cur_weapon['ReinforceLevel']
                            总次数 = 0
                            while self.game.Game.connected:
                                Global.LOGD(self.game_index, f"[装备强化]->ID:{cur_weapon['ItemUniqueID']},目标等级:{目标等级+1}")
                                self.game_fun.Req_CAItemReinforceReq(int(cur_weapon['ItemUniqueID']), 目标等级+1)
                                总次数 += 1
                                Result = self.game.Result.get("Result",None)
                                Error = self.game.Result.get("Error", None)
                                if Result:
                                    目标等级= Result[0]['Item']['ReinforceLevel']
                                    Global.LOGD(self.game_index,f"[装备强化]->强化完成,ID:{cur_weapon['ItemUniqueID']},目标等级:{目标等级}")
                                    if 目标等级 >=6:
                                        break
                                elif Error=="E_NOT_ENOUGH_GOLD":
                                    Global.LOGD(self.game_index,f"[装备强化]->金币不足,不强化")
                                    break
                                elif 总次数>=6:
                                    break





            self.自动_跳过剧情([4001, 20001, 401])  # 强化阵营 引导  401是对话
            deck_type = 100
            Decks = self.game.Info['player_deck'].get("Decks", None)
            if Decks:
                基地目标英雄 = 100514
                cur_deck = next((deck for deck in Decks if deck['DeckType'] == deck_type), None)  # 只获取type为1的编组数据
                if cur_deck:
                    DeckPositionUID1 = cur_deck['DeckPositionUID1']
                    hero_list = self.game.Info['player_hero']
                    cur_hero = next((hero for hero in hero_list if hero['HeroTid'] == 基地目标英雄), 0)
                    if int(DeckPositionUID1) == 0 and cur_hero:
                        self.game_fun.Req_CASavePlayerDeckReq([int(cur_hero['HeroUid'])], 0, deck_type)

                    PCGroupTIDs = self.game.Info['hero_first_talk'].get('PCGroupTIDs', [])
                    目标GourpID=10051
                    if not PCGroupTIDs or 目标GourpID not in PCGroupTIDs:  #
                        self.game_fun.Req_CAHeroFirstTalkReq(目标GourpID)
                        self.game_fun.Req_CAAgitTalkHeroReq(目标GourpID)
            # 升级引导
            target_formationGroup_id = 12300
            player_formation = self.game.Info.get('player_formation', [])
            formation_level = next((formation['Level'] for formation in player_formation if
                                    formation.get('FormationGroup', 0) == target_formationGroup_id), 0)
            if formation_level == 1:
                Global.LOGD(self.game_index, f"[阵型]->升级阵形,ID:{target_formationGroup_id},等级:{formation_level}")
                self.game_fun.Req_CAFormationLevelUpReq(target_formationGroup_id, formation_level + 1)

            #检测使用 三星装备套装
            inventory_consumable =self.game.Info.get('inventory_consumable',None)
            if inventory_consumable:
                cur_item = next((item for item in inventory_consumable if item['ItemTemplateID']== 201000023),None)
                if cur_item:
                    Global.LOGD(self.game_index, f"[背包]->使用三星装备套装")
                    self.game_fun.Req_CAOpenItemBoxReq(int(cur_item['ItemUniqueID']), cur_item['Count'])
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->活动_远征队_前置任务:{e}")
        return False
    def 活动_远征队(self):
        try:
            if not self.game.Info.get('guide_mission',None):
                return True
            self.活动_远征队_前置任务()
            time.sleep(1)
            while self.game.Game.connected:
                是否领取过奖励 = False
                Mission_list = self.game.Info['guide_mission'].get('Missions',[])[:]
                if Mission_list:
                    config_grouped = defaultdict(list)
                    for item in Global.G_Dbc['guide_quest_mission']:
                        config_grouped[item["EventMainTID"]].append(item)
                    for key, mission_list in config_grouped.items():
                        领奖ID = 0
                        for cf_mission in mission_list:
                            TID = cf_mission['TID']
                            cur_mission = next((mission for mission in Mission_list if mission['MissionID'] == TID), None)  # and mission['IsComplete'] ==True and mission['IsReceived'] == False
                            if cur_mission:
                                if cur_mission['IsComplete'] == True and cur_mission['IsReceived'] == False:
                                    领奖ID = TID
                            else:
                                if 领奖ID > 0 and 领奖ID not in [240]:
                                    Global.LOGD(self.game_index, f"[远征]->领取远征奖励,ID:{领奖ID}")
                                    self.game.GameFun.Req_CAGuideQuestMissionRewardReq(领奖ID)
                                    Error = self.game.Result.get('Error', None)
                                    if Error:
                                        领奖ID = 0
                                        Global.LOGE(self.game_index,f"[远征]->领取远征奖励失败,ID:{领奖ID},错误:{Error}")
                                        break
                                    是否领取过奖励 =True
                                    if 领奖ID == 7:
                                        ResultReward =self.game.Result.get('ResultReward', None)
                                        if ResultReward:
                                            cur_item =next((item for item in ResultReward['StackItems'] if int(item['ItemTemplateID'])==201000023),None)#
                                            if cur_item:
                                                ItemUniqueID = cur_item['ItemUniqueID']
                                                count=cur_item['Count']
                                                Global.LOGD(self.game_index, f"[背包]->使用三星装备套装")
                                                self.game_fun.Req_CAOpenItemBoxReq(int(ItemUniqueID),count)
                                    领奖ID = 0
                                break
                time.sleep(1)
                if not 是否领取过奖励:
                    break

            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->活动_远征队:{e}")
        return False
    def 领取_委托奖励(self):
        try:
            if not self.game.Info.get('individual_mission',None):
                return True

            Mission_list = self.game.Info['individual_mission'].get("Mission", [])
            dbc_individual_mission = Global.G_Dbc['individual_mission']
            for mission in Mission_list:
                MissionID = mission['MissionID']
                Count = mission['Count']
                IsComplete = mission['IsComplete']
                IsReceived = mission['IsReceived']
                if IsComplete and not IsReceived and Count > 0:  # and int(time.time())*1000 >NextDailyRenewalTimeMS
                    cur_dbc_mission= next((dbc_info for dbc_info in dbc_individual_mission if dbc_info['MissionID'] == MissionID),None)
                    dbc_count = 1
                    if cur_dbc_mission:
                        dbc_count =cur_dbc_mission['Count']
                        # PeriodType = cur_dbc_mission['PeriodType']
                        # self.game_fun.Req_CAIndividualMissionRewardAllReq()
                        # Global.LOGD(self.game_index, f"[委托]->领取委托奖励")
                        # return True
                    次数 =int(Count // dbc_count)
                    for index in range(0,次数):
                        Global.LOGD(self.game_index, f"[委托]->领取委托奖励,ID:{MissionID},次数:{index+1}/{次数}")
                        self.game_fun.Req_CAIndividualMissionRewardReq(MissionID)
                        Error = self.game.Result.get('Error', None)
                        if Error:
                            Global.LOGE(self.game_index, f"[委托]->领取委托奖励,ID:{MissionID},错误:{Error}")
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->领取_委托奖励:{e}")
        return False
    def 领取_事件奖励(self):
        try:
            Mission_list = self.game.Info.get('event_mission',[])
            for mission in Mission_list:
                MissionID = mission['MissionID']
                Count = mission['Count']
                IsComplete = mission['IsComplete']
                IsReceived = mission['IsReceived']
                if IsComplete and not IsReceived and Count > 0:  # and int(time.time())*1000 >NextDailyRenewalTimeMS
                    Global.LOGD(self.game_index, f"[事件]->领取事件奖励,ID:{MissionID}")
                    self.game_fun.Req_CAEventMissionRewardReq(MissionID)
                    Error = self.game.Result.get('Error', None)
                    if Error:
                        Global.LOGE(self.game_index, f"[事件]->领取事件奖励,ID:{MissionID},错误:{Error}")
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->领取_委托奖励:{e}")
        return False
    def 领取_通行证奖励(self):
        try:
            battle_pass =self.game.Info.get('battle_pass',None)
            if not battle_pass:
                return True
            #self.game.Info['battle_pass'].get()
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->领取_通行证奖励:{e}")
        return False
    def 自动_购买商店物品(self):
        shop_gold_limit = Global.G_GlobalConfig.get('shop_gold_limit','')
        is_shop = Global.G_GlobalConfig.get('is_shop', False)
        if not is_shop:
            return True
        try:
            待购买物品列表=[60000217,60000218,60000229,60000230,60000241,60000242]
            relay_shop =self.game.Info.get('relay_shop',[])
            for shop in relay_shop:
                event_main_tid = shop["EventMainTID"]
                for goods in shop["RelayGoods"]:
                    tid = goods["TID"]
                    buy_count = goods["BuyCount"]
                    if buy_count==0 and tid in 待购买物品列表:
                        Global.LOGD(self.game_index,f"[接力商店]->商店ID：{event_main_tid},购买物品:{tid}")
                        self.game_fun.Req_CABuyShopGoodsReq(tid,1)
                        Error = self.game.Result.get('Error', None)
                        if Error:
                            Global.LOGE(self.game_index, f"[接力商店]->购买物品失败,商店ID：{event_main_tid},购买物品:{tid},错误:{Error}")
            代购买物品列表=[30000001,30000009]
            self.game_fun.Req_CAConditionGoodsReq()
            condition_goods =self.game.Info.get('condition_goods',[])
            for good_info in condition_goods:
                ShopGoodsTID = good_info['ShopGoodsTID']
                BuyCount = good_info['BuyCount']
                if BuyCount==0 and ShopGoodsTID in 代购买物品列表:
                    Global.LOGD(self.game_index, f"[特别商店]->购买物品:{ShopGoodsTID}")
                    self.game_fun.Req_CABuyShopGoodsReq(ShopGoodsTID, 1)
                    Error = self.game.Result.get('Error', None)
                    if Error:
                        Global.LOGE(self.game_index,f"[特别商店]->购买物品失败,购买物品:{ShopGoodsTID},错误:{Error}")
            #商店购买
            代购买物品列表 =[10104100,10102001,10101001,10000001,10001001,10001002,10001003,20000005] #10001001 10001002 10001003  20000003收费
            self.game_fun.Req_CAGetShopReq()  #
            shop_list = self.game.Info.get('shop', [])
            for shop_info in shop_list:
                Goods = shop_info.get("Goods", [])
                for goods_info in Goods:
                    tid = goods_info['TID']
                    BuyCount = goods_info.get('BuyCount', 0)
                    if BuyCount == 0 and tid in 代购买物品列表:
                        if tid in [10001002, 10001003]:
                            count = 10
                            金币 = self.取_货币数量(502)
                            if shop_gold_limit and 金币 < int(shop_gold_limit):
                                continue
                        elif tid in [20000005]:
                            count = 6
                        else:
                            count = 1
                        Global.LOGD(self.game_index, f"[商店]->购买物品:{tid},数量:{count}")
                        self.game_fun.Req_CABuyShopGoodsReq(tid, count)
                        Error = self.game.Result.get('Error', None)
                        if Error:
                            Global.LOGE(self.game_index, f"[商店]->购买物品失败,购买物品:{tid},错误:{Error}")

            purchase = self.game.Info.get('purchase', {})
            if purchase:
                AccumulatePurchaseDay = purchase.get("AccumulatePurchaseDay",0)
                RewardReceiveDay = purchase.get("RewardReceiveDay", 0)
                if AccumulatePurchaseDay>0 and AccumulatePurchaseDay>RewardReceiveDay:
                    self.game_fun.Req_CAAccumulatePurchaseRewardReq(AccumulatePurchaseDay)
                    
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->自动_购买商店物品:{e}")
        return False
    def 自动_跳过剧情(self,tutorial_list):
        try:
            for id in tutorial_list:
                Status = 0
                if self.game.Info['player_tutorial']:
                    tutorial_info = next((item for item in self.game.Info['player_tutorial']['Tutorial'] if item['TutorialID'] == id),None)
                    if tutorial_info:
                        Status = tutorial_info["Status"]
                        if Status == 3:
                            continue
                Global.LOGD(self.game_index, f"[引导]->跳过引导:{id}")
                if not self.跳过剧情(id, Status):
                    # Global.LOGE(self.game_index, f"[引导]->跳过引导失败:{id}")
                    pass
        except Exception as e:
            Global.LOGE(self.game_index,f"[引导异常]->异常：{e}")
        return False
    def 领取_关卡奖励(self):
        try:
            StarAchievementIDs = self.game.Info['player_stage'].get('StarAchievementIDs', [])
            StageResults = self.game.Info['player_stage'].get('StageResults', [])
            last_LandMarkID= 0
            is_recv = False
            for dbc_info in Global.G_Dbc['stage_achievement_reward']:
                StarAchievementID = dbc_info['StarAchievementID']
                Difficulty = dbc_info['Difficulty']
                if StarAchievementID not in StarAchievementIDs  and Difficulty == 0:#暂时不考虑困难关卡
                    LandMarkID = dbc_info['LandMarkID']
                    if last_LandMarkID!=LandMarkID:
                        last_LandMarkID = LandMarkID
                        is_recv =False
                    if is_recv:
                        continue
                    StarCount = dbc_info['StarCount']
                    #统计星星数
                    star_sum = defaultdict(int)
                    for item in StageResults:
                        group = item["StageId"] // 100000
                        star_sum[group] += item["CompleteStar"]

                    cur_stars = star_sum[LandMarkID]
                    if cur_stars >= StarCount:
                        Global.LOGD(self.game_index, f"[关卡奖励]->领取关卡奖励,ID：{LandMarkID},星数:{cur_stars}")
                        self.game_fun.Req_CAStageAchievementRewardReq(LandMarkID,Difficulty)
                        is_recv = True
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->领取_关卡奖励：{e}")
        return False
    def 自动_使用背包物品(self):
        try:
            # "ItemName_202000034", "一般英雄召喚券"
            # "ItemName_202000035", "高級英雄召喚券"
            # "ItemName_202000036", "稀有英雄召喚券"
            # "ItemName_202000037", "傳說英雄召喚券II"
            使用物品列表=[202000034,202000035,202000036,202000037]
            bag_consumable = self.game.Info.get('inventory_consumable',[])
            if len(bag_consumable)==0:
                return True
            for item_id in 使用物品列表:
                item_info = next((item for item in bag_consumable if item.get('ItemTemplateID',0) == item_id),0)
                if item_info:
                    Global.LOGD(self.game_index, f"[消耗品]->使用物品：{item_info['ItemTemplateID']},数量:{item_info['Count']}")
                    self.game_fun.Req_CAOpenItemBoxReq(int(item_info['ItemUniqueID']),item_info['Count'])
            return True
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->自动_使用背包物品：{e}")
        return False
    def 背包_取物品信息(self,bag_name,item_id):
        try:
            bag_info = self.game.Info.get(bag_name, [])
            item_info = next((item for item in bag_info if item.get('ItemTemplateID', 0) == item_id), None)
            return item_info
        except Exception as e:
            Global.LOGE(self.game_index, f"[异常]->自动_使用背包物品：{e}")
        return None
    def 自动_合成英雄(self):
        #强化非编组 且ssr为3的4星以上的英雄,材料使用  ssr低于3的且星星小于4的 星星
        #1、检测是否有2个+5 的5星、4星 英雄
        #2、检测可强化的 ssr为3的4星英雄  优先有强化过的
        #3、检测作为强化材料的英雄  ssr小于3的并且小于4星的英雄,用来当强化材料
        try:
            排除英雄=['伊凡','卡琳','艾黎爾']
            is_compose_hero = Global.G_GlobalConfig.get('is_compose_hero',False)
            if not is_compose_hero:
                return True
            while self.game.Game.connected:
                stage_info = self.关卡_完成信息(200010)
                if not stage_info:
                    return True
                self.自动_跳过剧情([1001])
                self.打开_功能([800])
                hero_list = self.game.Info['player_hero']
                for hero in hero_list:
                    config = self.取卡片配置信息('pctable', hero['HeroTid'])
                    if config:
                        hero['Rarity'] = config['Rarity']
                        hero['Role'] = config['Role']
                        hero['Star'] = config['Star']
                        hero['Playable'] = config['Playable']
                        hero['name'] = config['name']
                        hero['subname'] = config['subname']

                sorted_hero =sorted(hero_list,key=lambda x: (-x.get('Lv',0), -x.get('Rarity', 0), -x.get('Star', 0), -x['ReinforceLevel']))
                #1、获取 编组列表的英雄
                deck_list = [int(uid) for item in self.game.Info['player_deck']['Decks'] for uid in [item[f'DeckPositionUID{i}'] for i in range(1, 6)]]
                可合成列表=[hero for hero in sorted_hero if hero['Rarity'] == 3 and hero['Star']==5 and hero['ReinforceLevel'] == 5 and hero['HeroUid'] not in deck_list and hero['name'] not in 排除英雄]
                if len(可合成列表)>=2: #说明有可以合成的英雄
                    # 先按 Star 排序（groupby 要求输入已排序）
                    data_sorted = sorted(可合成列表, key=lambda x: x['Star'])
                    # 按 Star 分组
                    是否合成 = False
                    合成分组列表 = {star: list(items) for star, items in groupby(data_sorted, key=lambda x: x['Star'])}
                    for star, 同星级英雄列表 in 合成分组列表.items():
                        if len(同星级英雄列表)>=2:
                            是否合成 = True
                            合成英雄 = [int(hero['HeroUid']) for hero in 同星级英雄列表[:2]]
                            Global.LOGD(self.game_index,f"[英雄合成]->星级:{star},英雄1:{同星级英雄列表[0]['name']} {同星级英雄列表[0]['Star']}☆,英雄2:{同星级英雄列表[1]['name']} {同星级英雄列表[1]['Star']}☆")
                            self.game_fun.Req_CAHeroComposeReq(合成英雄)
                            Error = self.game.Result.get("Error", None)
                            if Error == "E_USING_IN_REPETITION_BATTLE":
                                Global.LOGD(self.game_index, f"[英雄合成]->合成英雄编组冲突,重新获取强化数据")
                                break
                            elif Error == "E_NOT_ENOUGH_GOLD":
                                Global.LOGD(self.game_index, f"[英雄强化]->金币不足,停止强化")
                                return True
                            elif Error:
                                Global.LOGD(self.game_index, f"[英雄合成]->合成错误:{Error}")
                                continue
                            ResultHeroComposes = self.game.Result.get("ResultHeroComposes", None)
                            if ResultHeroComposes:
                                ResultHeroTID = ResultHeroComposes[0]['ResultHeroTID']
                                config = self.取卡片配置信息('pctable', ResultHeroTID)
                                if config:
                                    #print(f"[英雄合成]->合成成功,英雄:{config['name']} {config['Star']}☆,类别:{config['Rarity']}")
                                    Global.LOGD(self.game_index,f"[英雄合成]->合成成功,英雄:{config['name']} {config['Star']}☆,类别:{config['Rarity']}")
                                    time.sleep(1)

                    if 是否合成:#有合成动作都重新获取数据
                        continue

                待进化英雄 = [hero for hero in sorted_hero if hero['Rarity'] == 3 and hero['Star'] == 4 and hero['ReinforceLevel'] == 5 and hero['HeroUid'] not in deck_list and hero['name'] not in 排除英雄]
                是否进化 = False
                for 目标进化英雄 in 待进化英雄:
                    HeroUid = 目标进化英雄['HeroUid']
                    hero_name = 目标进化英雄['name']
                    Star = 目标进化英雄['Star']
                    Role = 目标进化英雄['Role']
                    Playable = 目标进化英雄['Playable']

                    cur_material_info = next((material_info for material_info in Global.G_Dbc['pc_evolution_material'] if material_info['Star'] == Star and material_info['Role'] == Role), None)
                    if cur_material_info:
                        MaterialID = cur_material_info['MaterialID']
                        Need_Count = cur_material_info['Count']
                        CostGold = cur_material_info['CostGold']
                        if self.取_货币数量(502) < CostGold:
                            Global.LOGD(self.game_index, f"[背包]->金币不足,无法进化英雄")
                            return True
                        item_info = self.背包_取物品信息('inventory_meterial', MaterialID)
                        背包_物品数量 = item_info['Count'] if item_info else 0
                        if 背包_物品数量 < Need_Count:  # 数量不足,考虑兑换
                            # 先判断需要什么兑换材料
                            cur_conversion = next((item_info for item_info in Global.G_Dbc['conversion'] if item_info['RewardID'] == MaterialID and item_info['TabGroup']== Playable), None)
                            if not cur_conversion:
                                continue
                            conversion_id = cur_conversion['TID']
                            兑换材料ID = cur_conversion['MaterialID']
                            兑换材料消耗数量 = cur_conversion['MaterialCount']
                            兑换奖励数量 = cur_conversion['RewardCount']
                            兑换材料_需求数量 = math.ceil((Need_Count - 背包_物品数量) / 兑换奖励数量) * 兑换材料消耗数量
                            item_info = self.背包_取物品信息('inventory_meterial', 兑换材料ID)
                            背包_兑换材料数量 = item_info['Count'] if item_info else 0
                            if 背包_兑换材料数量 < 兑换材料_需求数量:
                                box_info = self.背包_取物品信息('inventory_consumable', 203000015)  # 材料箱子
                                背包_材料箱子数量 = box_info['Count'] if box_info else 0
                                if 背包_材料箱子数量 < 兑换材料_需求数量:
                                    continue
                                Global.LOGD(self.game_index, f"[背包]->使用进化材料选择箱,获取物品:{兑换材料ID},数量:{兑换材料_需求数量}")
                                self.game_fun.Req_CAOpenItemBoxReq(int(box_info['ItemUniqueID']), 兑换材料_需求数量,兑换材料ID)
                                Error = self.game.Result.get("Error", None)
                                if Error:
                                    Global.LOGD(self.game_index, f"[背包]->使用进化材料选择箱失败：{Error}")
                                    continue
                            Global.LOGD(self.game_index,f"[背包]->分解进化材料,{兑换材料ID}->{MaterialID},数量:{兑换材料_需求数量}")
                            self.game_fun.Req_CAConversionReq(conversion_id, 兑换材料_需求数量)
                            Error = self.game.Result.get("Error", None)
                            if Error:
                                Global.LOGD(self.game_index, f"[背包]->分解进化材料失败：{Error}")
                                continue
                            item_info = self.背包_取物品信息('inventory_meterial', MaterialID)  # 再获取一次背包数据
                            背包_兑换材料数量 = item_info['Count'] if item_info else 0
                            if 背包_兑换材料数量 < 兑换材料_需求数量:
                                continue
                    Global.LOGD(self.game_index, f"[英雄进化]->进化目标:{hero_name}")
                    self.game_fun.Req_CAHeroEvolutionReq(int(HeroUid))
                    Error = self.game.Result.get("Error", None)
                    if Error:
                        Global.LOGD(self.game_index, f"[英雄进化]->进化失败：{Error}")
                        continue
                    Global.LOGD(self.game_index, f"[英雄进化]->进化目标:{hero_name},进化成功")
                    是否进化 = True
                if 是否进化:
                    continue

                待强化英雄列表 = [hero for hero in sorted_hero if hero['Rarity'] == 3 and hero['Star'] <6 and hero['ReinforceLevel'] < 5 and hero['HeroUid'] not in deck_list and hero['name'] not in 排除英雄]
                强化材料列表 = [hero for hero in sorted_hero if hero['Rarity'] <3 and hero['Star'] < 4 and hero['ReinforceLevel'] == 0 and hero['HeroUid'] not in deck_list and hero['name'] not in 排除英雄]
                if len(强化材料列表) >0 and len(待强化英雄列表) >0:# 可强化
                    强化目标 = 待强化英雄列表[0]
                    dbc_cost= next((dbc_info for dbc_info in Global.G_Dbc['pc_reinforcement_cost'] if dbc_info['PCStar'] == 强化目标['Star'] and dbc_info['PCReinforcementLevel'] == 强化目标['ReinforceLevel']),None)
                    if dbc_cost:
                        cost = dbc_cost['PCReinforcementCost']
                        材料列表= [int(hero['HeroUid']) for hero in 强化材料列表[-10:] ]
                        Global.LOGD(self.game_index,f"[英雄强化]->目标英雄:{强化目标['name']},材料数量:{len(材料列表)}")
                        self.game_fun.Req_CAHeroReinforceReq(int(强化目标['HeroUid']),材料列表,len(材料列表)*cost)
                        Error = self.game.Result.get("Error",None)
                        if Error=="E_USING_IN_REPETITION_BATTLE":
                            Global.LOGD(self.game_index,f"[英雄强化]->强化英雄编组冲突,重新获取强化数据")
                            break
                        elif Error=="E_NOT_ENOUGH_GOLD":
                            Global.LOGD(self.game_index, f"[英雄强化]->金币不足,停止强化")
                            return True
                        time.sleep(1)
                else:
                    break#没有可强化的
            return True
        except Exception as e:
            Global.LOGE(f"异常定位:{traceback.format_exc()}")
            Global.LOGE(self.game_index, f"[异常]->自动_合成英雄：{e}")
        return False

    def Handle_Script(self):
        start_time = time.time()
        while self.game.Game.connected:#如果连接成功才
            try:
                if not self.game.isInit:
                    time.sleep(2)  # 未初始化延时2秒
                    end_time = time.time()
                    if (end_time-start_time) >60:
                        Global.LOGE(self.game_index, f"[错误]->进入游戏超时...")
                        break
                    continue

                # 1、检测第一关是否完成
                if not self.关卡_完成信息(100001):
                    if not self.关卡_战斗(100001):
                        return False
                AccountName = self.game.Info['login_ack']["AccountName"]
                if not AccountName or "$" in AccountName:
                    self.打开_功能([300, 2700, 2800])
                    while self.game.Game.IsConnect:
                        name = Global.取随机字符串(3, 16, True, True, True, True)
                        Global.LOGD(self.game_index, f"[名称]->设置角色名称:{name}")
                        self.game_fun.Req_CAChangePlayerNickNameReq(name)
                        Error = self.game.Result.get('Error', None)
                        if not Error:
                            break


                tutorial_list=[111,701,301,501,3801,30001]#,,3801(强化装备),30001(头像上的奖励)
                self.自动_跳过剧情(tutorial_list)

                self.抽卡_默认抽卡(19)

                # 检测邮件
                if not self.自动_邮件():
                    return False
                self.抽卡_默认抽卡(15)


                self.引导_穿戴装备()
                if not self.普通_抽卡():
                    return False
                if not self.自动_关卡():
                    return False


                if not self.领取_关卡奖励():
                    return False
                if not self.自动_购买商店物品():
                    return False
                if not self.自动_图鉴奖励():
                    return False
                if not self.活动_远征队():
                    return False
                if not self.领取_委托奖励():
                    return False
                if not self.领取_事件奖励():
                    return False
                if not self.自动_邮件():#抽卡之前要先获取邮件
                    return False
                if not self.普通_抽卡():#领取奖励后再抽一次
                    return False
                if not self.自动_使用背包物品():#自动使用消耗品
                    return False
                if not self.自动_合成英雄():
                    return False
                if not self.自动_抽卡():
                    return False
                if not self.自动_重复关卡战斗():
                    return False
                time.sleep(2)#等待数据更新
                return True
            except Exception as e:
                Global.LOGE(self.game_index,f"[异常]->Handle_Script:{e}")
        return False